#include "log.h"
#include "response.h"
#include "parse.h"


char log_buf[LOG_BUF_SIZE];
//解析文件类型

void parse_file_type(char *filename, char *file_type){   
    if (strstr(filename, ".html"))
        strcpy(file_type, "text/html");
    else if (strstr(filename, ".css"))
        strcpy(file_type, "text/css");
    else if (strstr(filename, ".js"))
        strcpy(file_type, "application/javascript");
    else if (strstr(filename, ".gif"))
        strcpy(file_type, "image/gif");
    else if (strstr(filename, ".png"))
        strcpy(file_type, "image/png");
    else if (strstr(filename, ".jpg") || strstr(filename, "jpeg"))
        strcpy(file_type, "image/jpeg");
    else if (strstr(filename, ".wav"))
        strcpy(file_type, "audio/x-wav");
    else
        strcpy(file_type, "text/plain");
}

int send_get_header(int client_sock, Request *request) {
    // header
        struct tm tm;
        struct stat sbuf;
        time_t now;
        char   filename[BUF_SIZE], content[BUF_SIZE], filetype[TYPE_LEN], tbuf[TYPE_LEN], dbuf[TYPE_LEN]; 

        char uri[255] = ".";
        strcat(uri, request->http_uri);
        if(strcmp(uri, "./") == 0) {
            strcat(uri, "static_site/index.html");
        }
        int fd_in = open(uri, O_RDONLY);
        if(fd_in < 0) {
            char str[] = "HTTP/1.1 404 Not Found\r\n\r\n";
            log_write(str, TRUE, 1);
            send(client_sock, str, strlen(str), 0);

            return -1;
        }

        stat(uri, &sbuf);
        parse_file_type(uri, filetype);
            
        tm = *gmtime(&sbuf.st_mtime);
        strftime(tbuf, TYPE_LEN, "%a, %d %b %Y %H:%M:%S %Z", &tm);
        now = time(0);
        tm = *gmtime(&now);
        strftime(dbuf, TYPE_LEN, "%a, %d %b %Y %H:%M:%S %Z", &tm);

        sprintf(content, "HTTP/1.1 200 OK\r\n");
        if (client_sock == 0)
            sprintf(content, "%sConnection: close\r\n", content);
        else
            sprintf(content, "%sConnection: keep-alive\r\n", content);

        sprintf(content, "%sContent-Length: %ld\r\n", content, sbuf.st_size);
        sprintf(content, "%sContent-Type: %s\r\n", content, filetype);
        sprintf(content, "%sDate: %s\r\n", content, dbuf);
        sprintf(content, "%sLast-Modified: %s\r\n", content, tbuf);
        sprintf(content, "%sServer: Liso/1.0\r\n\r\n", content);

        if(strcasecmp(request->http_method, "GET") == 0){
            char buf[8192];
            int read_ret = read(fd_in, buf, sizeof(buf));
            strcat(content, buf);
        }
        send(client_sock, content, strlen(content), 0);
        sprintf(log_buf,"Http Method: %s\n",request->http_method);
        log_write(log_buf, TRUE, 0);

        #ifdef DEBUG    
        printf("GET send header: %s \n", content);
        #endif

    return 0;
}

void parse_request(int client_sock, char* buf, ssize_t readret) {
    Request *request = parse(buf, readret, client_sock);
    // 格式错误，返回400
    if(request == NULL) {
        char str[] = "HTTP/1.1 400 Bad request\r\n\r\n";
        log_write(str, TRUE, 1);
        send(client_sock, str, strlen(str), 0);
        // free(request->headers);
        free(request);
        memset(buf, 0, BUF_SIZE);
        printf("Invalid HTTP header!\n");
        return;
    }
    // HTTP版本错误，返回505
    if(strcasecmp(request->http_version, "HTTP/1.1") != 0) {
        char str[] = "HTTP/1.1 505 HTTP Version not supported\r\n\r\n";
        log_write(str, TRUE, 1);
        send(client_sock, str, strlen(str), 0);
        free(request->headers);
        free(request);
        memset(buf, 0, BUF_SIZE);
        printf("Invalid HTTP version!\n");
        return;
    }



    if(strcasecmp(request->http_method, "GET") && 
        strcasecmp(request->http_method, "HEAD") && 
        strcasecmp(request->http_method, "POST")) {

        char str[] = "HTTP/1.1 501 Not Implemented\r\n\r\n";
        log_write(str, TRUE, 1);
        send(client_sock, str, strlen(str), 0);
        free(request->headers);
        free(request);
        memset(buf, 0, BUF_SIZE);
        printf("Method not supported \n");
        return;
    }

    // 处理HEAD, GET, POST
    if(strcasecmp(request->http_method, "HEAD") == 0){	
        printf(" HEAD request \n");
        send_get_header(client_sock, request);
        log_write(log_buf, TRUE, 0);

    }
    else if(strcasecmp(request->http_method, "GET") == 0)
    {
        /*
         *有关GET请求的一点补充：
         *把static_site设置成默认目录，把index.html设置成默认网页。
         *当收到GET请求时按照"./static_site"+request->http_uri+"index.html"这个路径去寻找网页，如果能找到就正常返回响应，如果找不到就返回404响应。
         */
	    printf(" GET request \n");
        // validate_request_file(client_sock, request);
        
        send_get_header(client_sock, request);
        }
    else if(strcasecmp(request->http_method, "POST") == 0)
    {
        printf(" POST request \n");
        sprintf(log_buf,"Http Method: %s\n",request->http_method);
        log_write(log_buf, TRUE, 0);
        //handle_post_request(index, request);
        send(client_sock, buf, readret, 0);
    }

    free(request->headers);
    free(request);
    return;
}